package com.wonder.media;

import java.util.ArrayList;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.ViewGroup.LayoutParams;

public class DefaultPlayer extends Player implements
		MediaPlayer.OnBufferingUpdateListener,
		MediaPlayer.OnCompletionListener, MediaPlayer.OnErrorListener,
		MediaPlayer.OnInfoListener, MediaPlayer.OnPreparedListener,
		MediaPlayer.OnSeekCompleteListener,
		MediaPlayer.OnVideoSizeChangedListener{
	
	private ArrayList<PlayerEventListener> listeners = new ArrayList<PlayerEventListener>();
	
	private static DefaultPlayer player = null;
	
	private SurfaceView mview;
	
	private int width = 0, height = 0;
	
	private static int mdisplayWidth = 0, mdisplayHeight = 0;

	private MediaPlayer mMediaPlayer = null;
	
	public static DefaultPlayer getInstance(String workspace, boolean overlayUsed, int overlayFormat){
//		if(player == null){
			player = new DefaultPlayer();
//		}
		return player;
	}
	
	private DefaultPlayer(){
		mMediaPlayer = new MediaPlayer();
		mMediaPlayer.setOnBufferingUpdateListener(this);
		mMediaPlayer.setOnCompletionListener(this);
		mMediaPlayer.setOnErrorListener(this);
		mMediaPlayer.setOnInfoListener(this);
		mMediaPlayer.setOnPreparedListener(this);
		mMediaPlayer.setOnSeekCompleteListener(this);
		mMediaPlayer.setOnVideoSizeChangedListener(this);
	}

	@Override
	public boolean init(SurfaceView view, String SocketName,
			String httpUserAgent, int nFirmwareVersion, int nRenderType,
			int nVideoFormat, int nColorTab, int nAndroidVer) {
		// TODO Auto-generated method stub
		try {
			mview = view;

			mdisplayWidth = mdisplayWidth == 0 ? view.getWidth() : mdisplayWidth;
			mdisplayHeight = mdisplayHeight == 0 ? view.getHeight() : mdisplayHeight;

			mMediaPlayer.reset();
			mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
		} catch (Exception e) {

		}
		return false;
	}

	@Override
	public void start(String dataSource, int pos) {
		// TODO Auto-generated method stub
		try {
			mMediaPlayer.setDataSource(dataSource);
			mMediaPlayer.prepare();
			mMediaPlayer.start();
			if(pos != 0)
				mMediaPlayer.seekTo(pos*1000);
		} catch (Exception e) {

		}
	}

	@Override
	public void seekTo(int sec) {
		// TODO Auto-generated method stub
		try {
			mMediaPlayer.seekTo(sec*1000);
		} catch (Exception e) {

		}
	}

	@Override
	public void play() {
		// TODO Auto-generated method stub
		try {
			mMediaPlayer.start();
		} catch (Exception e) {

		}
	}

	@Override
	public void pause() {
		// TODO Auto-generated method stub
		try {
			mMediaPlayer.pause();
		} catch (Exception e) {

		}
	}

	@Override
	public void stop() {
		// TODO Auto-generated method stub
		try {
			mMediaPlayer.stop();
		} catch (Exception e) {

		}
	}

	@Override
	public void close() {
		// TODO Auto-generated method stub
		try {
			mMediaPlayer.setDisplay(null);
			mMediaPlayer.release();
		} catch (Exception e) {

		}
		player = null;
	}

	@Override
	public void suspend() {
		// TODO Auto-generated method stub
//		try {
//			mMediaPlayer.stop();
//		} catch (Exception e) {
//			Log.e(LOGTAG, "pause()");
//		}
	}

	@Override
	public void resume() {
		// TODO Auto-generated method stub
//		try {
//			mMediaPlayer.resume();
//		} catch (Exception e) {
//			Log.e(LOGTAG, "pause()");
//		}
	}

	@Override
	public void updateSurface(SurfaceHolder holder, int x, int y,
			int widthPixels, int heightPixels) {
		// TODO Auto-generated method stub
		if(holder == null){
			return;
		}
		try {
			mMediaPlayer.setDisplay(holder);
		} catch (Exception e) {

		}
	}

	@Override
	public int getPassedSec() {
		// TODO Auto-generated method stub
		int ret = -1;
		try {
			ret = mMediaPlayer.getCurrentPosition();
		} catch (Exception e) {
			return -1;
		}
		return ret/1000;
	}

	@Override
	public int getDuration() {
		// TODO Auto-generated method stub
		int ret = -1;
		try {
			ret = mMediaPlayer.getDuration();
		} catch (Exception e) {
			return -1;
		}
		return ret/1000;
	}

	@Override
	public int getBufferPercentage() {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public int getPlayerStatus() {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public void addPlayerEventListener(PlayerEventListener listener) {
		// TODO Auto-generated method stub

		synchronized(this){
			if (!listeners.contains(listener))
				listeners.add(listener);
		}
	}

	@Override
	public void removePlayerEventListener(PlayerEventListener listener) {
		// TODO Auto-generated method stub

		synchronized(this){
			listeners.remove(listener);
		}
	}

	public void onVideoSizeChanged(MediaPlayer mp, int nwidth, int nheight) {
		// TODO Auto-generated method stub
		width = nwidth;
		height = nheight;
		notifyEvent(new PlayerVideoSizeEvent(PlayerEvent.PLAYER_EVENT_SIZE, width, height));
	}

	public void onSeekComplete(MediaPlayer mp) {
		// TODO Auto-generated method stub
		
	}

	public void onPrepared(MediaPlayer mp) {
		// TODO Auto-generated method stub
		notifyEvent(new PlayerStatusEvent(PlayerEvent.PLAYER_EVENT_PREPARE, EPlayerStatus_NULL));
	}

	public boolean onInfo(MediaPlayer mp, int what, int extra) {
		// TODO Auto-generated method stub
		return false;
	}

	public boolean onError(MediaPlayer mp, int what, int extra) {
		// TODO Auto-generated method stub
		notifyEvent(new PlayerStatusEvent(PlayerEvent.PLAYER_EVENT_ERROR, EPlayerStatus_NULL));
		return false;
	}

	public void onCompletion(MediaPlayer mp) {
		// TODO Auto-generated method stub
		notifyEvent(new PlayerStatusEvent(PlayerEvent.PLAYER_EVENT_STATUS, EPlayerStatus_EndOfStream));
	}

	public void onBufferingUpdate(MediaPlayer mp, int percent) {
		// TODO Auto-generated method stub
		notifyEvent(new PlayerBufferPercentEvent(PlayerEvent.PLAYER_EVENT_BUFFER, percent));
	}
	
	@SuppressWarnings("unchecked")
	private void notifyEvent(PlayerEvent event){
		ArrayList<PlayerEventListener> temp;
		synchronized(this){
			temp = (ArrayList<PlayerEventListener>)listeners.clone();
		}
		for(PlayerEventListener l:temp){
			l.postPlayerEvent(event);
		}
	}

	@Override
	public void destroy() {
		// TODO Auto-generated method stub
	}

	@Override
	public void setVideoMode(int mode) {
		// TODO Auto-generated method stub
		changeSurfaceSize(mview, mode);
	}

	protected void changeSurfaceSize(SurfaceView surface, int ar) {
		int videoWidth = width;//player.getVideoWidth();
		int videoHeight = height;//player.getVideoHeight();
		int displayWidth = mdisplayWidth, displayHeight = mdisplayHeight;
		if (videoWidth <= 0 || videoHeight <= 0) {
			return;
		}
		SurfaceHolder holder = surface.getHolder();
		holder.setFixedSize(videoWidth, videoHeight);
		int targetWidth = -1;
		int targetHeight = -1;
		switch (ar) {
		
		default:
			break;
		}
		if (targetWidth > 0 && targetHeight > 0) {
			double ard = (double) displayWidth / (double) displayHeight;
			double art = (double) targetWidth / (double) targetHeight;
			if (ard > art) {
				displayWidth = displayHeight * targetWidth / targetHeight;
			} else {
				displayHeight = displayWidth * targetHeight / targetWidth;
			}
		}
		LayoutParams lp = surface.getLayoutParams();
		lp.width = displayWidth;
		lp.height = displayHeight;
		surface.setLayoutParams(lp);
		surface.invalidate();
	}

	@Override
	public int getwidth() {
		// TODO Auto-generated method stub
		int ret = -1;
		try {
			ret = mMediaPlayer.getVideoWidth();
		} catch (Exception e) {
			return -1;
		}
		return ret;
	}

	@Override
	public int getheight() {
		// TODO Auto-generated method stub
		int ret = -1;
		try {
			ret = mMediaPlayer.getVideoHeight();
		} catch (Exception e) {
			return -1;
		}
		return ret;
	}
}